package com.nulldev.util.data.FastMath.impls;

import com.nulldev.util.data.FastMath.Math;

public class TaylorMath extends Math {

	public static final TaylorMath INSTANCE = new TaylorMath();
	private static final float BF_SIN_TO_COS;

	public static float sin(final float rad) {
		final double x = rad;
		final double x2 = x * x;
		final double x3 = x2 * x;
		final double x4 = x2 * x3;
		final double x5 = x2 * x4;
		final double x6 = x2 * x5;
		final double x7 = x2 * x6;
		final double x8 = x2 * x7;
		final double x9 = x2 * x8;
		final double x10 = x2 * x9;
		double val = x;
		val -= x3 * 0.16666666666666666;
		val += x4 * 0.008333333333333333;
		val -= x5 * 1.984126984126984E-4;
		val += x6 * 2.7557319223985893E-6;
		val -= x7 * 2.505210838544172E-8;
		val += x8 * 1.6059043836821613E-10;
		val -= x9 * 7.647163731819816E-13;
		val += x10 * 2.8114572543455206E-15;
		return (float) val;
	}

	public static double sin(final double rad) {
		final double x = rad;
		final double x2 = x * x;
		final double x3 = x2 * x;
		final double x4 = x2 * x3;
		final double x5 = x2 * x4;
		final double x6 = x2 * x5;
		final double x7 = x2 * x6;
		final double x8 = x2 * x7;
		final double x9 = x2 * x8;
		final double x10 = x2 * x9;
		double val = x;
		val -= x3 * 0.16666666666666666;
		val += x4 * 0.008333333333333333;
		val -= x5 * 1.984126984126984E-4;
		val += x6 * 2.7557319223985893E-6;
		val -= x7 * 2.505210838544172E-8;
		val += x8 * 1.6059043836821613E-10;
		val -= x9 * 7.647163731819816E-13;
		val += x10 * 2.8114572543455206E-15;
		return val;
	}

	public static float cos(final float rad) {
		return sin(rad + TaylorMath.BF_SIN_TO_COS);
	}

	public static double cos(final double rad) {
		return sin(rad + TaylorMath.BF_SIN_TO_COS);
	}

	static {
		BF_SIN_TO_COS = 1.5707964f;
	}
}
